package cn.harry.modular.sys.service.impl;

import cn.harry.modular.sys.mapper.SysRoleMapper;
import cn.harry.modular.sys.domain.SysRole;
import cn.harry.modular.sys.domain.SysRoleDept;
import cn.harry.modular.sys.domain.SysRoleMenu;
import cn.harry.modular.sys.domain.SysUserRole;
import cn.harry.modular.sys.service.SysRoleDeptService;
import cn.harry.modular.sys.service.SysRoleMenuService;
import cn.harry.modular.sys.service.SysRoleService;
import cn.harry.modular.sys.service.SysUserRoleService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 后台用户角色表
 *
 * @author honghh Date 2019-10-12 10:55:44 Copyright (C) www.tech-harry.cn
 */
@RequiredArgsConstructor
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
		implements SysRoleService {

	private final SysRoleMenuService sysRoleMenuService;

	private final SysUserRoleService sysUserRoleService;

	private final SysRoleDeptService sysRoleDeptService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean create(SysRole sysRole) {
		boolean re = save(sysRole);
		sysRoleMenuService.insertRoleAndRoleMenu(sysRole.getId(), sysRole.getMenuIds());
		return re;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean update(Long id, SysRole sysRole) {
		sysRoleMenuService.remove(
				new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, id));
		if (!CollectionUtil.isEmpty(sysRole.getMenuIds())) {
			// 保存角色与菜单关系
			sysRoleMenuService.insertRoleAndRoleMenu(sysRole.getId(),
					sysRole.getMenuIds());
		}
		return updateById(sysRole);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteByIds(Long[] ids) {
		for (Long id : ids) {
			// 删除角色与菜单关联
			sysRoleMenuService.remove(
					Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getRoleId, id));
			// 删除角色与用户关联
			sysUserRoleService.remove(
					Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getRoleId, id));
		}
		return removeBatchByIds(Arrays.asList(ids));
	}

	@Override
	public boolean dataScope(SysRole sysRole) {
		Long roleId = sysRole.getId();
		// 修改角色信息
		updateById(sysRole);
		// 删除角色与部门关联
		sysRoleDeptService.deleteRoleDeptByRoleId(roleId);
		// 新增角色和部门信息（数据权限）
		return insertRoleDept(sysRole);
	}

	@Override
	public int updateRoleStatus(SysRole role) {
		return this.baseMapper.updateById(role);
	}

	@Override
	public List<SysRole> getExportList(SysRole sysRole) {
		LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>(sysRole);

		if (StrUtil.isNotEmpty(sysRole.getBeginTime())) {
			wrapper.gt(SysRole::getCreateTime, sysRole.getBeginTime());
		}

		if (StrUtil.isNotEmpty(sysRole.getEndTime())) {
			wrapper.lt(SysRole::getCreateTime, sysRole.getEndTime());
		}
		return list(wrapper);
	}

	/**
	 * 新增角色部门信息(数据权限)
	 * @param role 角色对象
	 */
	public boolean insertRoleDept(SysRole role) {
		List<SysRoleDept> list = new ArrayList<>();
		for (Long deptId : role.getDeptIds()) {
			SysRoleDept rd = new SysRoleDept();
			rd.setRoleId(role.getId());
			rd.setDeptId(deptId);
			list.add(rd);
		}
		return sysRoleDeptService.saveBatch(list);
	}

}